/*
 * Copyright (c) 2001-2008, TIBCO Software Inc.
 * Use, modification, and distribution subject to terms of license.
 */

(function(plugIn) {

// if(demo.uxcore.ExtendPane) delete demo.uxcore.ExtendPane;
jsx3.lang.Class.defineClass("demo.uxcore.ExtendPane", jsx3.gui.Block, [demo.uxcore.IListAccessory],
  function(EXTEND, extend) {
    
    EXTEND.Logger = jsx3.util.Logger.getLogger(EXTEND.jsxclass.getName());
    EXTEND.IEXTENDABLE = 'demo.uxcore.IExtendable';

    extend.jsxcontrolVeto = true;
    extend._jsxisWorking = false;

    extend.setControlVeto = function(value){
      this.jsxcontrolVeto = value;
      return this;
    };

    extend.getControlVeto = function() {
      return this.jsxcontrolVeto;
    };

    extend.setExtendPaneHeight = function(height) {
      this.jsxextendpaneheight = height;
      this._relayoutListContainer();
      return this;
    };

    extend.getExtendPaneHeight = function() {
      return this.jsxextendpaneheight;
    };

    /**
     * sets component height and recalculate template
     * @override
     */
    extend.setHeight = function(height, bPaint) {
      this.jsxsuper(parseInt(height+''), bPaint);
      this._relayoutListContainer();
      return this;
    };

    /**
     * sets component display mode and recalculate template
     * @override
     */
    extend.setDisplay = function(display, bPaint) {
      this.jsxsuper(display, bPaint);
      this._relayoutListContainer();
      return this;
    };

    extend._relayoutListContainer = function(objParent) {
      try {
        (this.getListContainer() || objParent).syncProperty(["viewChange", "viewHeight"]);
      } catch(e) {
        EXTEND.Logger.error('relayout ListContainer error...' + jsx3.NativeError.wrap(e));
      }
    };

    /**
     * Returns the value of the dynamic property @strPropName
     * @param strPropName {String} id for this dynamic property among all properties
     * @param strToken {String...} if present tokens such as {0}, {1}, {n} will be replaced with the nth element of this vararg array
     * @return {String} value of the property
     */
    extend.getProperty = function(strPropName, strToken) {
      return plugIn.getServer().getDynamicProperty(strPropName, strToken);
    };

    /**
     * It is a utility funciton to set multiple (list them in objSetting:property) dynamic properties together
     * @param objJSX {Object}
     * @param objSetting {Array} properties list
     * @param bNotSave {Boolean} if <code>true</code>,this value will not be saved to GUI
     */
    extend.setDefaultProperty = function(objJSX, objSetting, bNotSave) {
      for(var i in objSetting) {
        objJSX.setDynamicProperty(i, objSetting[i], bNotSave);
      };
      return objJSX;
    };

    /**
     * instance initializer
     * @param strName {String} unique name distinguishing this object from all other JSX GUI objects in the JSX application
     * @param strHTML {String} Text/HTML markup to place in the jsx3.gui.Block instance
     */
    extend.init = function(strName, strHTML) {
      // note that top, left, width and height are removed.  These shall be controlled by the parent container.
      this.jsxsuper(strName,strHTML);
    };

    extend.onSetParent = function(objParent){
      var ret = this.jsxsuper(objParent);
      if(!objParent.instanceOf("demo.uxcore.ListContainer")) {
        ret = false;
      }
      if(!ret && jsx3.IDE) {
        EXTEND.Logger.warn("Building Error: Only ListContainer is valid parent of " + this.getClass().getName());
      }
      return ret;
    };

    extend.onSetChild = function(objChild) {
      if(!objChild.instanceOf("demo.uxcore.IExtendable")) {
        EXTEND.Logger.warn("Building Error: Only IExtendable implementations are valid children of " + this.getClass().getName());
        return false;
      }
      return true;
    };

    extend.onChildAdded = function(objChild) {
      var extension = this.getExtension(objChild.getExtendId());
      if (!extension) {
        this._extensions[objChild.getExtendId()] = objChild;
      }
      /* show last added child, for develop */
      if(jsx3.IDE) this.show(objChild);
    };

    extend.getAllExtendPanes = function(){
      if(!jsx3.Class.forName(EXTEND.IEXTENDABLE)) return [];
      return this.getDescendantsOfType(EXTEND.IEXTENDABLE, true);
    };

    extend.getExtension = function(extendId){
      if(!this._extensions) this._extensions = {};
      return this._extensions[extendId];
    };

    /**
     * Show one of the extended pane which already painted in, others will be hide.
     * @param extendObj {<demo.uxcore.IExtendable>} - the implementation class of demo.uxcore.IExtendable interface.
     */
    extend.show = function(extendObj) {
      jsx3.$A(this.getAllExtendPanes()).each(jsx3.$F(function(pane){
        var extension = this.getExtension(extendObj.getExtendId());
        if (!extension) {
          EXTEND.Logger.error('#show:: extension "' + extendObj + '" not found.');
        } else {
          extension.setDisplay((pane.getExtendId() == extension.getExtendId() ? jsx3.gui.Block.DISPLAYBLOCK : jsx3.gui.Block.DISPLAYNONE), true);
        }
      }).bind(this));
    };

    /**
     * Hide extendpane.
     */
    extend.hide = function() {
      this.setDisplay(jsx3.gui.Block.DISPLAYNONE, true); 
    };

    /**
     * Show or hide extendpane.
     */
    extend.toggle = function() {
      this.setDisplay(this.getDisplay() == jsx3.gui.Block.DISPLAYNONE ? jsx3.gui.Block.DISPLAYBLOCK : jsx3.gui.Block.DISPLAYNONE, true); 
    };

    /********************* INTERFACE IMPLEMENTATIONS *********************/
    extend.searchRequested = function(searchXML) {
        // do nothing...empty implementation to comply with IListAccessoryInterface
    };

    extend.recordEdited = function(strRecordId, strAction, entityRecord, strInsertBefore, objCaller) {
        // do nothing...empty implementation to comply with IListAccessoryInterface
    };

    extend.viewChanged = function(strNewListViewId, strOldListViewId) {
        // do nothing...empty implementation to comply with IListAccessoryInterface
    };

    extend.actionRequested = function(actionId) {
        // do nothing...empty implementation to comply with IListAccessoryInterface
    };

    extend.visibilityChanged = function(bVisible) {
        // do nothing...empty implementation to comply with IListAccessoryInterface
    };

    extend.refreshRequested = function() {
        // do nothing...empty implementation to comply with IListAccessoryInterface
    };

    extend.columnsChanged = function(arrNewAtts, arrOldAtts) {
        // do nothing...empty implementation to comply with IListAccessoryInterface
    };

    /**
     * Used to notify this accessory that a data change was performed.
     *
     * @param dataCDF {jsx3.xml.CDF.Document} - the CDF document of new data, null indicates data was cleared,
     *        while empty document indicates query returned no results.
     * @param intCurrentPage {int} - the page number of the data, with respect to the whole data set
     * @param intTotalPages {int} - the total pages in the data set of which this data represents a single page
     * @param strId {String} - and auxilliary id for the target of the data
     */
    extend.dataChanged = function(dataCDF, intCurrentPage, intTotalPages, strId) {
        // can be used to know when a search has been applied.  The first time this is called after a notification on the searchRequested
        // function should (at least in theory) be the results after applying the search
        this._jsxisWorking = false;
    };

    extend.pageChangeRequested = function(intNewPage, intOldPage, intTotalPages) {
        // do nothing...empty implementation to comply with IListAccessoryInterface
    };

    /**
     * Used to tell the accessory to reset itself.  Should be implemented by each accessory to reset their own state.
     */
    extend.reset = function() {
      jsx3.$A(this.getAllExtendPanes()).each(function(pane){
        try{
          pane['reset'] && pane['reset'].apply(pane);
        }catch(e){
          EXTEND.Logger.error('error call "reset" method...' + jsx3.NativeError.wrap(e));
        }
      });
    };

    /**
     * Used to notify this accessory that a reset is being requested.
     * Is called before the ListContainer performs the actual reset.
     *
     * @return {boolean} <code>true</code> to allow the reset, <code>false</code> to veto it.
     */
    extend.onReset = function() {
        return (!this.jsxcontrolVeto || !this._jsxisWorking);
    };

    extend.onViewChange = function(strNewListViewId, strOldListViewId){
        return (!this.jsxcontrolVeto || !this._jsxisWorking);
    };

    extend.onAction = function(actionId){
        return (!this.jsxcontrolVeto || !this._jsxisWorking);
    };

    extend.onVisibilityChange = function(bVisible){
        return (!this.jsxcontrolVeto || !this._jsxisWorking);
    };

    extend.onRefresh = function(){
        return (!this.jsxcontrolVeto || !this._jsxisWorking);
    };

    extend.onColumnsChange = function(arrNewAtts, arrOldAtts){
        return (!this.jsxcontrolVeto || !this._jsxisWorking);
    };

    extend.onSelectRecordIds = function(arrRecordIds){
        return (!this.jsxcontrolVeto || !this._jsxisWorking);
    };

    extend.onClearSelectedRecordIds = function(){
        return (!this.jsxcontrolVeto || !this._jsxisWorking);
    };

    extend.recordsSelected = function(arrRecordIds) {
        // do nothing...empty implementation to comply with IListAccessoryInterface
    };

    extend.selectionCleared = function() {
        // do nothing...empty implementation to comply with IListAccessoryInterface
    };
  }
);

})(this);